package com.epam.edu.task01.tourism.voucher;

import com.epam.edu.task01.tourism.residence.Nutrition;
import com.epam.edu.task01.tourism.residence.ResidenceInformation;
import com.epam.edu.task01.tourism.residence.ResidenceType;
import com.epam.edu.task01.tourism.road.RoadInformation;
import com.epam.edu.task01.tourism.road.Route;
import com.epam.edu.task01.tourism.road.Transport;
import org.apache.log4j.Logger;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

public class VouchersList {
	private static Logger logger = Logger.getLogger(VouchersList.class);
	private List<Voucher> vouchers = new LinkedList<Voucher>();

	public VouchersList() {
		super();
	}

	public void addVoucher(String voucherType, String data)
			throws ParseException {
		try {
			String datas[] = data.split("\\|");
			if (voucherType.equals("VoucherToCruise")) {
				addVoucherToCruise(datas);
            }
            if (voucherType.equals("VoucherToExcursion")) {
				addVoucherToExcursion(datas);
			}
            if (voucherType.equals("VoucherToRelax")) {
				addVoucherToRelax(datas);
			}
            if (voucherType.equals("VoucherToShopping")) {
				addVoucherToShopping(datas);
			}
            if (voucherType.equals("VoucherToTreatment")) {
				addVoucherToTreatment(datas);
			}
		} catch (ParseException exception) {
			logger.error(exception.getMessage());
		}
	}

	private void addVoucherToCruise(String... datas) throws ParseException {
		if (datas.length != 8) {
			logger.error("Insufficient data");
			return;
		}
		Transport transportType = Transport.valueOf(datas[4]);
		Route routeType = Route.valueOf(datas[5]);
		RoadInformation road = new RoadInformation(transportType, routeType,
				Integer.parseInt(datas[6]));
		Date firstDate = parseDate(datas[2]);
		Date secondDate = parseDate(datas[3]);
		VoucherToCruise voucher = new VoucherToCruise(
				Integer.parseInt(datas[0]), datas[1], firstDate, secondDate,
				road, Integer.parseInt(datas[7]));
		vouchers.add(voucher);
	}

	private void addVoucherToExcursion(String... datas) throws ParseException {
		if (datas.length != 9) {
			logger.error("iInsufficient data");
			return;
		}
		Transport transportType = Transport.valueOf(datas[4]);
		Route routeType = Route.valueOf(datas[5]);
		RoadInformation road = new RoadInformation(transportType, routeType,
				Integer.parseInt(datas[6]));
		Date date = parseDate(datas[3]);
		VoucherToExcursion voucher = new VoucherToExcursion(
				Integer.parseInt(datas[0]), datas[1], datas[2], date, road,
				Integer.parseInt(datas[7]), Integer.parseInt(datas[8]));
		vouchers.add(voucher);
	}

	private void addVoucherToRelax(String... datas) throws ParseException {
		if (datas.length != 12) {
			logger.error("iInsufficient data");
			return;
		}
		ResidenceType residenceType = ResidenceType.valueOf(datas[3]);
		Nutrition nutrition = Nutrition.valueOf(datas[5]);
		Date firstDate = parseDate(datas[7]);
		Date secondDate = parseDate(datas[8]);
		ResidenceInformation residence = new ResidenceInformation(
				residenceType, datas[4], nutrition, Integer.parseInt(datas[6]),
				firstDate, secondDate);
		Transport transportType = Transport.valueOf(datas[9]);
		Route routeType = Route.valueOf(datas[10]);
		RoadInformation road = new RoadInformation(transportType, routeType,
				Integer.parseInt(datas[11]));
		VoucherToRelax voucher = new VoucherToRelax(Integer.parseInt(datas[0]),
				datas[1], datas[2], residence, road);
		vouchers.add(voucher);
	}

	private void addVoucherToShopping(String... datas) throws ParseException {
		if (datas.length != 13) {
			logger.error("iInsufficient data");
			return;
		}
		ResidenceType residenceType = ResidenceType.valueOf(datas[3]);
		Nutrition nutrition = Nutrition.valueOf(datas[5]);
		Date firstDate = parseDate(datas[7]);
		Date secondDate = parseDate(datas[8]);
		ResidenceInformation residence = new ResidenceInformation(
				residenceType, datas[4], nutrition, Integer.parseInt(datas[6]),
				firstDate, secondDate);
		Transport transportType = Transport.valueOf(datas[9]);
		Route routeType = Route.valueOf(datas[10]);
		RoadInformation road = new RoadInformation(transportType, routeType,
				Integer.parseInt(datas[11]));
		VoucherToShopping voucher = new VoucherToShopping(
				Integer.parseInt(datas[0]), datas[1], datas[2], residence,
				road, Integer.parseInt(datas[12]));
		vouchers.add(voucher);
	}

	private void addVoucherToTreatment(String... datas) throws ParseException {
		if (datas.length != 13) {
			logger.error("iInsufficient data");
			return;
		}
		ResidenceType residenceType = ResidenceType.valueOf(datas[3]);
		Nutrition nutrition = Nutrition.valueOf(datas[5]);
		Date firstDate = parseDate(datas[7]);
		Date secondDate = parseDate(datas[8]);
		ResidenceInformation residence = new ResidenceInformation(
				residenceType, datas[4], nutrition, Integer.parseInt(datas[6]),
				firstDate, secondDate);
		Transport transportType = Transport.valueOf(datas[9]);
		Route routeType = Route.valueOf(datas[10]);
		RoadInformation road = new RoadInformation(transportType, routeType,
				Integer.parseInt(datas[11]));
		VoucherToTreatment voucher = new VoucherToTreatment(
				Integer.parseInt(datas[0]), datas[1], datas[2], residence,
				road, Integer.parseInt(datas[12]));
		vouchers.add(voucher);
	}

    public String searchVouchersByType(String voucherType){
        StringBuilder result =new StringBuilder();
        for (Voucher str : this.vouchers) {
            if (voucherType.equals("VoucherToCruise") && str instanceof VoucherToCruise) {
                result.append(str.toString() + "\n");
            }
            if (voucherType.equals("VoucherToExcursion") && str instanceof VoucherToExcursion) {
                result.append(str.toString() + "\n");
            }
            if (voucherType.equals("VoucherToRelax") && str instanceof VoucherToRelax) {
                result.append(str.toString() + "\n");
            }
            if (voucherType.equals("VoucherToShopping") && str instanceof VoucherToShopping) {
                result.append(str.toString() + "\n");
            }
            if (voucherType.equals("VoucherToTreatment") && str instanceof VoucherToTreatment) {
                result.append(str.toString() + "\n");
            }
        }
        return result.toString();
    }

	private Date parseDate(String dateString) throws ParseException {
		DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.ENGLISH);
		Date date = dateFormat.parse(dateString);
		return date;
	}

	@Override
	public String toString() {
		StringBuilder voucherList = new StringBuilder();
		for (Voucher str : this.vouchers) {
			voucherList.append(str.toString() + "\n");
		}
		return voucherList.toString();
	}

}
